﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace Utity
{
    /// <summary>
    /// 对传入传出的JSON,数据请求加密
    /// </summary>
    public class RSASupport
    {
        const string DEFAULT_KEY = "BBFFTT!@#QWE";
        const string APP_KEYT = "KEYT";
        public static string GetAppKeyt()
        {
            string keyt = System.Configuration.ConfigurationManager.AppSettings[APP_KEYT];
            return string.IsNullOrEmpty(keyt) ? DEFAULT_KEY : keyt;
        }

        //加密
        public static string Encryption(string express)
        {
            CspParameters param = new CspParameters();      
            param.KeyContainerName = GetAppKeyt();//密匙容器的名称，保持加密解密一致才能解密成功
            
            param.Flags=  CspProviderFlags.UseDefaultKeyContainer;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
                
                Byte[] PlaintextData = System.Text.Encoding.UTF8.GetBytes(express);
                int MaxBlockSize = rsa.KeySize / 8 - 11;    //加密块最大长度限制

                if (PlaintextData.Length <= MaxBlockSize)
                {
                    return Convert.ToBase64String(rsa.Encrypt(PlaintextData, true));

                }
                using (MemoryStream PlaiStream = new MemoryStream(PlaintextData))
                using (MemoryStream CrypStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
                    while (BlockSize > 0)
                    {
                        Byte[] ToEncrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);

                        Byte[] Cryptograph = rsa.Encrypt(ToEncrypt, true);
                        CrypStream.Write(Cryptograph, 0, Cryptograph.Length);

                        BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
                    }
                    return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
                }
            }
        }

        //解密
        public static string Decrypt(string ciphertext)
        {
            CspParameters param = new CspParameters();
            param.KeyContainerName = GetAppKeyt();
           
            param.Flags = CspProviderFlags.UseDefaultKeyContainer;
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(param))
            {
               
                Byte[] CiphertextData = Convert.FromBase64String(ciphertext);
                int MaxBlockSize = rsa.KeySize / 8;    //解密块最大长度限制

                if (CiphertextData.Length <= MaxBlockSize)
                {
                    return Encoding.UTF8.GetString(rsa.Decrypt(CiphertextData, true));
                }
                using (MemoryStream CrypStream = new MemoryStream(CiphertextData))
                using (MemoryStream PlaiStream = new MemoryStream())
                {
                    Byte[] Buffer = new Byte[MaxBlockSize];
                    int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
                    while (BlockSize > 0)
                    {
                        Byte[] ToDecrypt = new Byte[BlockSize];
                        Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);

                        Byte[] Plaintext = rsa.Decrypt(ToDecrypt, true);
                        PlaiStream.Write(Plaintext, 0, Plaintext.Length);
                        BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
                    }
                    return Encoding.UTF8.GetString(PlaiStream.ToArray());
                }
            }
        }
    }
}
